package iorichina.hellojava.hellosample.valid_sudoku;

import iorichina.hellojava.hellosample.org.springframework.util.Assert;

class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        /// [[".",".",".",".","5",".",".","1","."]
        /// ,[".","4",".","3",".",".",".",".","."]
        /// ,[".",".",".",".",".","3",".",".","1"]
        /// ,["8",".",".",".",".",".",".","2","."]
        /// ,[".",".","2",".","7",".",".",".","."]
        /// ,[".","1","5",".",".",".",".",".","."]
        /// ,[".",".",".",".",".","2",".",".","."]
        /// ,[".","2",".","9",".",".",".",".","."]
        /// ,[".",".","4",".",".",".",".",".","."]]=>false
        {
            char[][] board = {
                    {'.', '.', '.', '.', '5', '.', '.', '1', '.'},
                    {'.', '4', '.', '3', '.', '.', '.', '.', '.'},
                    {'.', '.', '.', '.', '.', '3', '.', '.', '1'},
                    {'8', '.', '.', '.', '.', '.', '.', '2', '.'},
                    {'.', '.', '2', '.', '7', '.', '.', '.', '.'},
                    {'.', '1', '5', '.', '.', '.', '.', '.', '.'},
                    {'.', '.', '.', '.', '.', '2', '.', '.', '.'},
                    {'.', '2', '.', '9', '.', '.', '.', '.', '.'},
                    {'.', '.', '4', '.', '.', '.', '.', '.', '.'}
            };
            boolean validSudoku = solution.isValidSudoku(board);
            System.out.println(validSudoku);
            Assert.isTrue(!validSudoku, "Invalid Sudoku should return false");
        }
        /// [["5","3",".",".","7",".",".",".","."]
        /// ,["6",".",".","1","9","5",".",".","."]
        /// ,[".","9","8",".",".",".",".","6","."]
        /// ,["8",".",".",".","6",".",".",".","3"]
        /// ,["4",".",".","8",".","3",".",".","1"]
        /// ,["7",".",".",".","2",".",".",".","6"]
        /// ,[".","6",".",".",".",".","2","8","."]
        /// ,[".",".",".","4","1","9",".",".","5"]
        /// ,[".",".",".",".","8",".",".","7","9"]]=>true
        {
            char[][] board = {
                    {'5', '3', '.', '.', '7', '.', '.', '.', '.'},
                    {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
                    {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
                    {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
                    {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
                    {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
                    {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
                    {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
                    {'.', '.', '.', '.', '8', '.', '.', '7', '9'}
            };
            boolean validSudoku = solution.isValidSudoku(board);
            System.out.println(validSudoku);
            Assert.isTrue(validSudoku, "Valid Sudoku should return true");
        }
        ///[["8","3",".",".","7",".",".",".","."]
        /// ,["6",".",".","1","9","5",".",".","."]
        /// ,[".","9","8",".",".",".",".","6","."]
        /// ,["8",".",".",".","6",".",".",".","3"]
        /// ,["4",".",".","8",".","3",".",".","1"]
        /// ,["7",".",".",".","2",".",".",".","6"]
        /// ,[".","6",".",".",".",".","2","8","."]
        /// ,[".",".",".","4","1","9",".",".","5"]
        /// ,[".",".",".",".","8",".",".","7","9"]]
        {
            char[][] board = {
                    {'8', '3', '.', '.', '7', '.', '.', '.', '.'},
                    {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
                    {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
                    {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
                    {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
                    {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
                    {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
                    {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
                    {'.', '.', '.', '.', '8', '.', '.', '7', '9'}
            };
            boolean validSudoku = solution.isValidSudoku(board);
            System.out.println(validSudoku);
            Assert.isTrue(!validSudoku, "Invalid Sudoku should return false");
        }
    }

    public boolean isValidSudoku(char[][] board) {
        boolean[][] row = new boolean[9][9];
        boolean[][] column = new boolean[9][9];
        boolean[][][] rowColumn = new boolean[3][3][9];
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char c = board[i][j];
                if ('.' == c) {
                    continue;
                }
                int k = c - '1'; // Convert '1'-'9' to 0-8
                if (row[i][k] || column[j][k] || rowColumn[i / 3][j / 3][k]) {
                    return false;
                }
                row[i][k] = column[j][k] = rowColumn[i / 3][j / 3][k] = true;
            }
        }
        return true;
    }
}